package cn.ztuo.bitrade.listener;

import cn.ztuo.bitrade.constant.TransactionType;
import cn.ztuo.bitrade.dao.AccessRecordDao;
import cn.ztuo.bitrade.dao.MemberTransactionDao;
import cn.ztuo.bitrade.dao.MemberWalletDao;
import cn.ztuo.bitrade.entity.*;
import cn.ztuo.bitrade.service.*;
import cn.ztuo.bitrade.util.BigDecimalUtils;
import cn.ztuo.bitrade.util.Md5;
import cn.ztuo.bitrade.vendor.provider.SMSProvider;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 监听所有db的过期事件__keyevent@*__:expired"
 *
 * @author: Xiazt
 * @date: 2020-04-08 19:35
 */
@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    @Autowired
    private EarningsTreasureService earningsTreasureService;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Autowired
    private SMSProvider smsProvider;

    @Autowired
    private AccessRecordDao accessRecordDao;

    @Autowired
    private MemberService memberService;

    @Autowired
    private MemberWalletDao memberWalletDao;

    @Autowired
    private MemberTransactionDao memberTransactionDao;

    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private CesspitRecordService cesspitRecordService;
    @Autowired
    private MemberTransactionService transactionService;


    private final String BEFOREDAY_REMIND = "您的借入订单还剩余24小时到期，请及时处理！";
    private final String BORROW_REMIND = "您的借入订单已到期强平！";
    private final String LOAN_REMIND = "您的借出订单已到期强平，质押金已划转至您的账户！";

    public RedisKeyExpirationListener(@Qualifier("container") RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    /**
     * 针对redis数据失效事件，进行数据处理
     *
     * @param message
     * @param pattern
     */
    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onMessage(Message message, byte[] pattern) {
        // 获取过期Key
        String expiredKey = message.toString();
        if (expiredKey.contains(":")) {
            // 拆分key
            String[] keyArray = expiredKey.split(":");
            // 截取前缀
            String firstPrefix = keyArray[0];
            String secondPrefix = keyArray[1];
            // 截取出id
            String dataId = keyArray[2];
            log.info("firstPrefix={}", firstPrefix);
            log.info("secondPrefix={}", secondPrefix);
            log.info("dataId={}", dataId);

            if ("earningsTreasure".equals(firstPrefix)) {
                EarningsTreasure earningsTreasure = earningsTreasureService.getById(Long.parseLong(dataId));
                switch (secondPrefix) {
                    case "end":
                        // 收益宝筹募时间已结束
                        earningsTreasure.setStatus(0);
                        break;
                    case "start":
                        // 收益宝筹募时间已开始
                        earningsTreasure.setStatus(1);
                        break;
                }
                earningsTreasureService.inster(earningsTreasure);
            } else if ("earningsBuyRecord:earnings".equals(firstPrefix + ":" + secondPrefix)) {
                // 结算收益时间到
                kafkaTemplate.send("earningsBuyRecord", dataId, "结算收益").get();


            } else if ("repayTime".equals(firstPrefix)) {
                AccessRecord accessRecord = accessRecordDao.findById(Long.parseLong(dataId));
                BorrowMoney borrowMoney = accessRecord.getBorrowMoney();
                LoanMoney loanMoney = accessRecord.getLoanMoney();
                Member member = accessRecord.getJoinMember();
                try {
                    // 借贷
                    switch (secondPrefix) {
                        // 到期前一天 发短信
                        case "beforeDay":
                            String phoneNumber;
                            if (accessRecord.getType() == 0) {
                                phoneNumber = accessRecord.getJoinMember().getMobilePhone();
                            } else {
                                phoneNumber = accessRecord.getBorrowMoney().getJoinMember().getMobilePhone();
                            }
                            // Java
//                            smsProvider.sendSingleMessage(phoneNumber, BEFOREDAY_REMIND);
                            // PHP
                            sendPHPSMS(phoneNumber,BEFOREDAY_REMIND);

//                            accessRecord.setReminder(1);
                            accessRecordDao.save(accessRecord);
                            break;
                        // 到期自动平仓
                        case "difference":
                            if (accessRecord.getType() == 0) {
                                // 平仓 划转余额
                                MemberWallet loanWaller = memberWalletDao.findByCoinAndMemberId(accessRecord.getJoinPledgeCoin(), loanMoney.getJoinMember().getId());
                                loanWaller.setBalance(BigDecimalUtils.add(loanWaller.getBalance(), accessRecord.getPledgeMoney()));
                                memberWalletDao.save(loanWaller);
                                // 平仓资产流水
                                MemberTransaction memberTransaction = new MemberTransaction();
                                memberTransaction.setMemberId(loanMoney.getJoinMember().getId());
                                memberTransaction.setSymbol(accessRecord.getJoinPledgeCoin().getUnit());
                                memberTransaction.setCreateTime(new Date());
                                memberTransaction.setAmount(accessRecord.getPledgeMoney());
                                memberTransaction.setType(TransactionType.ACCESS_CLOSE_OUT);
                                memberTransactionDao.save(memberTransaction);
                                // 发短信 Java
//                                smsProvider.sendSingleMessage(accessRecord.getJoinMember().getMobilePhone(), BORROW_REMIND);
//                                smsProvider.sendSingleMessage(loanMoney.getJoinMember().getMobilePhone(), LOAN_REMIND);
                                // PHP
                                sendPHPSMS(accessRecord.getJoinMember().getMobilePhone(), BORROW_REMIND);
                                sendPHPSMS(loanMoney.getJoinMember().getMobilePhone(), LOAN_REMIND);
                            } else {
                                // 平仓 划转余额 计算比例 质押金 * （借入金额 / 总金额）
                                BigDecimal resultMoney = BigDecimalUtils.mul(borrowMoney.getPledgeMoney(), BigDecimalUtils.div(accessRecord.getMoney(), borrowMoney.getBorrowAmount()));
                                MemberWallet loanWaller = memberWalletDao.findByCoinAndMemberId(borrowMoney.getJoinPledgeCoin(), accessRecord.getJoinMember().getId());
                                loanWaller.setBalance(BigDecimalUtils.add(loanWaller.getBalance(), resultMoney));
                                memberWalletDao.save(loanWaller);
                                // 平仓资产流水
                                MemberTransaction memberTransaction = new MemberTransaction();
                                memberTransaction.setMemberId(accessRecord.getJoinMember().getId());
                                memberTransaction.setSymbol(borrowMoney.getJoinPledgeCoin().getUnit());
                                memberTransaction.setCreateTime(new Date());
                                memberTransaction.setAmount(resultMoney);
                                memberTransaction.setType(TransactionType.ACCESS_CLOSE_OUT);
                                memberTransactionDao.save(memberTransaction);

                                // 借贷是否完成 如未完成退回剩余质押金
                                if (borrowMoney.getStatus() != 2) {
                                    // 计算剩余质押金
                                    BigDecimal finishMoney = BigDecimalUtils.mul(borrowMoney.getPledgeMoney(), BigDecimalUtils.div(borrowMoney.getHasBorrowAmount(), borrowMoney.getBorrowAmount()));
                                    BigDecimal residueMoney = BigDecimalUtils.sub(borrowMoney.getPledgeMoney(), finishMoney);
                                    // 退回剩余质押金
                                    MemberWallet borrowMemberWallet = memberWalletDao.findByCoinAndMemberId(borrowMoney.getJoinPledgeCoin(), borrowMoney.getJoinMember().getId());
                                    borrowMemberWallet.setBalance(BigDecimalUtils.add(borrowMemberWallet.getBalance(), residueMoney));
                                    memberWalletDao.save(borrowMemberWallet);
                                    // 平仓剩余抵押资产流水
                                    MemberTransaction closeOutResidueTransaction = new MemberTransaction();
                                    closeOutResidueTransaction.setMemberId(borrowMoney.getJoinMember().getId());
                                    closeOutResidueTransaction.setSymbol(borrowMoney.getJoinPledgeCoin().getUnit());
                                    closeOutResidueTransaction.setCreateTime(new Date());
                                    closeOutResidueTransaction.setAmount(residueMoney);
                                    closeOutResidueTransaction.setType(TransactionType.ACCESS_CLOSE_OUT_RESIDUE);
                                    memberTransactionDao.save(closeOutResidueTransaction);
                                }

                                // 发短信 Java
//                                smsProvider.sendSingleMessage(member.getMobilePhone(), LOAN_REMIND);
//                                smsProvider.sendSingleMessage(borrowMoney.getJoinMember().getMobilePhone(), BORROW_REMIND);
                                // PHP
                                sendPHPSMS(member.getMobilePhone(), LOAN_REMIND);
                                sendPHPSMS(borrowMoney.getJoinMember().getMobilePhone(), BORROW_REMIND);
                            }
                            accessRecord.setStatus(3);
                            accessRecordDao.save(accessRecord);
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else if("orePool".equals(firstPrefix)){
                CesspitRecord ore = cesspitRecordService.findById(Long.parseLong(dataId));

                MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(ore.getCoin(),ore.getMemberId());
                memberWalletService.increaseBalance(memberWallet.getId(),new BigDecimal(secondPrefix));
                MemberTransaction transaction = new MemberTransaction();
                transaction.setAmount(new BigDecimal(secondPrefix));
                transaction.setSymbol(memberWallet.getCoin().getName());
                transaction.setAddress("");
                transaction.setMemberId(memberWallet.getMemberId());
                transaction.setType(TransactionType.REDEMPTION);
                transaction.setFee(BigDecimal.ZERO);
                transaction.setCreateTime(new Date());
                transaction.setRemark("赎回");
                transactionService.save(transaction);
            }
        }

    }

    public void sendPHPSMS(String phoneNumber, String content) {
        RestTemplate restTemplate = new RestTemplate();
        String md5 = Md5.md5String(phoneNumber + "f84012c66608000aada33bfd2d8b7636");
        String borrowUrl = "http://www.bodhi.luxe/api/Docking/send_sms?mobile=" + phoneNumber + "&content=" + content + "&auth_code=" + md5;
        //restTemplate.getForObject(borrowUrl, String.class);
    }

}
